package biz.datalk.industrialland.admin.modules.common.servie.impl;

import biz.datalk.commons.helper.collection.ListHelper;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.po.DynformField;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.po.DynformHead;
import biz.datalk.industrialland.admin.modules.common.mapper.ICommonMapper;
import biz.datalk.industrialland.admin.modules.common.servie.ICommonService;
import biz.datalk.industrialland.common.def.enums.DBYNEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author tarofang@163.com
 * @date 2019-12-19
 */
@Slf4j
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Service("commonService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class CommonServiceImpl implements ICommonService {

    @Autowired
    @Qualifier("jdbcTemplate")
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private ICommonMapper commonMapper;

    @Override
    public long getCountForJdbc(String sql) {
        Long count = this.jdbcTemplate.queryForObject(sql, Long.class);
        return count == null ? 0 : count;
    }

    @Override
    public long getCountForJdbc(String sql, Object... objs) {
        Long count = this.jdbcTemplate.queryForObject(sql, objs, Long.class);
        return count == null ? 0 : count;
    }

    @Override
    public List<Map<String, Object>> findForJdbc(String sql) {
        return jdbcTemplate.queryForList(sql);
    }

    @Override
    public List<Map<String, Object>> findForJdbc(String sql, Object... objs) {
        return jdbcTemplate.queryForList(sql, objs);
    }

    @Override
    public Map<String, Object> findOneForJdbc(String sql) {
        return jdbcTemplate.queryForMap(sql);
    }

    @Override
    public Map<String, Object> findOneForJdbc(String sql, Object... objs) {
        return jdbcTemplate.queryForMap(sql, objs);
    }

    @Override
    public int update(String sql) {
        return jdbcTemplate.update(sql);
    }

    @Override
    public int update(String sql, Object... objs) {
        return jdbcTemplate.update(sql, objs);
    }

    @Override
    public boolean judgeTableIsExit(String tableName) {
        if (StringUtils.isBlank(tableName)) {
            return false;
        }

        Connection conn = null;
        ResultSet rs = null;
        try {
            conn = jdbcTemplate.getDataSource().getConnection();

            DatabaseMetaData dbMetaData = conn.getMetaData();
            rs = dbMetaData.getTables(null, null, tableName, new String[]{"TABLE"});
            if (rs.next()) {
                // 表存在
                return true;
            } else {
                // 表不存在
                return false;
            }
        } catch (SQLException ex) {
            log.warn(ex.getMessage(), ex);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                log.warn(ex.getMessage(), ex);
            }
        }

        return false;
    }

    @Override
    public void createTable(DynformHead table, List<DynformField> fields) {
        String tableName = table.getTableName();
        String sql = "CREATE TABLE " + tableName ;
        StringBuilder sb = new StringBuilder();
        sb.append("CREATE TABLE ").append(tableName).append("(");

        List<String> pks = new ArrayList<>();
        boolean isFirst = true;
        for (DynformField field : fields) {
            if (!isFirst) {
                sb.append(",");
            } else {
                isFirst = false;
            }
            // sb.append("`user_id` int(11) NOT NULL DEFAULT '0' COMMENT ''");
            sb.append("`").append(field.getFieldName().trim()).append("` ");
            sb.append(field.getFieldType()).append("(").append(field.getFieldLength()).append(") ");
            if (StringUtils.equals(field.getFieldIsNull(), DBYNEnum.Y.name())) {
                sb.append("NOT NULL ");
            } else {
                sb.append("NULL ");
            }
            sb.append("DEFAULT '").append(StringUtils.trimToEmpty(field.getFieldDefault())).append("' ");
            sb.append("COMMENT '").append(field.getFieldComment()).append("'");
            if (StringUtils.equals(field.getFieldIsPk(), DBYNEnum.Y.name())) {
                pks.add(field.getFieldName().trim());
            }
        }
        // PRIMARY KEY (`id`) USING BTREE
        String combine = ListHelper.create().combine(pks, "`,`");
        sb.append("PRIMARY KEY (`").append(combine).append("`) USING BTREE");

        sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='").append(table.getTableComment()).append("'");

        String x = sb.toString();

        // TODO 创建表、更新表
        System.out.println(x);

    }

    @Override
    public List<biz.datalk.industrialland.admin.modules.online.dynform.pojo.dto.DictItem> selectDictFromCustomTable(String dictTable, String dictCode, String dictText) {
        return commonMapper.selectDictFromCustomTable(dictTable, dictCode, dictText);
    }

    @Override
    public List<biz.datalk.industrialland.admin.modules.online.dynform.pojo.dto.DictItem> selectDictFromSysdict(String dictCode) {
        return commonMapper.selectDictFromSysdict(dictCode);
    }

}
